"""
使用插件的方式来扩充ezflow的功能(实验性)
可能需要加载PLUGINS后使用修饰器的方法调用会比较好
TODO:仍需配合实例来实现
"""
from ezflow.utils.logger import get_logger
from importlib.metadata import entry_points
from dataclasses import dataclass, field

logger = get_logger(__name__)

def global_injects():
    """
    发现所有注册到`ezflow.plugins`组的插件函数并直接执行,
    在插件包的 `project.toml` 中插入
    ```
    [project.entry-points."ezflow.plugins"]
    global = "my_plugins:plugin_class"
    ```
    以暴露插件入口点
    """
    for entry in entry_points(name="global", group="ezflow.plugins"):
        distribution = entry.dist
        package_name = distribution.name
        try:
            logger.info(f"Loading plugin {entry.name} from {package_name}")
            inject = entry.load() 
            inject() # 执行
        except Exception as e:
            logger.error(f"执行注入:from {package_name} 失败: {e}")


# %% plugin
# 参考`pytest.mark`的设计, 将插件标记化, 
# 简易通过@ezflow.plugins.stream.xxx或者@ezflow.plugins.logging.xxx实现快速插件索引
class PluginMarker:
    """动态生成标记的类，类似 pytest.mark."""
    def __init__(self, entry_name):
        # 内部字典，用于存储所有通过 entry_points 加载的标记函数
        self._registered_plugins = {}
        self._register_marker(entry_name)

    def _register_marker(self, entry_name):
        """注册一个标记函数。"""
        for entry in entry_points(name=entry_name, group=f"ezflow.plugins.{entry_name}"):
            package_name = entry.dist.name
            logger.info(f"Registering plugin marker '{entry.name}' from {package_name} in {entry_name}")
            decorator = entry.load()
            self._registered_plugins[entry_name] = decorator

    def __getattr__(self, name):
        """当访问不存在的属性时，动态查找注册的标记函数。"""
        if name in self._registered_plugins:
            return self._registered_plugins[name]
        else:
            raise AttributeError(f"Marker '{name}' is not registered.")

# 创建一个全局的插件标记实例
@dataclass(slots=True)
class Plugin:
    stream: PluginMarker = field(default_factory=lambda: PluginMarker("stream"))
    logging: PluginMarker = field(default_factory=lambda: PluginMarker("logging"))

    def __repr__(self):
        return "<ezflow.plugin>"

plugins = Plugin()